package br.usp.ime.ingpos.services;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.usp.ime.ingpos.modelo.AreaDePesquisa;
import br.usp.ime.ingpos.modelo.Orientador;
import br.usp.ime.ingpos.modelo.TipoPerfil;
import br.usp.ime.ingpos.modelo.Usuario;
import br.usp.ime.ingpos.modelo.dao.AreaDePesquisaDAO;
import br.usp.ime.ingpos.modelo.dao.OrientadorDAO;
import br.usp.ime.ingpos.modelo.dao.PerfilDao;
import br.usp.ime.ingpos.seguranca.Criptografia;

@Component
@RequestScoped
public class OrientadorService
{
    private final OrientadorDAO orientadorDAO;
    private final AreaDePesquisaDAO areaDePesquisaDAO;
    private final PerfilDao perfilDAO;

    public OrientadorService(
        final OrientadorDAO orientadorDAO,
        final AreaDePesquisaDAO areaDePesquisaDAO,
        final PerfilDao perfilDAO )
    {
        this.orientadorDAO = orientadorDAO;
        this.areaDePesquisaDAO = areaDePesquisaDAO;
        this.perfilDAO = perfilDAO;
    }

    public void salvar(
        Orientador orientador )
    {
        if( orientador.getUsuarioID() == null ) {
        	
            final String senha = Criptografia.md5( orientador.getSenha() );
            final String hash = Criptografia.md5( orientador.getEmail()
                + orientador.getDadosPessoais().getNomeCompleto() );
            
            orientador.setPerfil( perfilDAO.findById(TipoPerfil.PROFESSOR.getId()) );
            orientador.setSenha( senha );
            orientador.setHash( hash );
        	
            orientadorDAO.saveOrUpdate( orientador );
        } else {
            Orientador orientadorPersistente = this.procurarPorId( orientador.getUsuarioID() );
            BeanUtils.copyProperties( orientador, orientadorPersistente, new String[] {
                "usuarioID"
            } );
            orientadorDAO.saveOrUpdate( orientadorPersistente );
        }
    }

    public void deletarOrientador(
        Orientador orientador )
    {
        final Orientador orientadorPersistente = this.procurarPorId( orientador.getUsuarioID() );
        orientadorDAO.delete( orientadorPersistente );
    }

    public List<Orientador> procurarTodosOrientadores()
    {
        return orientadorDAO.findByCriteria(Order.asc("dadosPessoais.nomeCompleto"));
    }

    public Orientador procuraOrientadorPorNome(
        String nome )
    {
        List<Orientador> orientadores = orientadorDAO.findByCriteria( 
        		Restrictions.eq( "dadosPessoais.nomeCompleto", nome ) );

        if( orientadores.isEmpty() )
            return null;

        return orientadores.get( 0 );
    }

    public Orientador procurarPorHash( String hash ) {
        List<Orientador> orientadores = orientadorDAO.findByCriteria( 
        		Restrictions.eq( "hash", hash ) );

        if( orientadores.isEmpty() )
            return null;

        return orientadores.get( 0 );
    }

    public Orientador procurarPorId(
        Long usuarioID )
    {
        List<Orientador> orientadores = orientadorDAO.findByCriteria( Restrictions.eq(
            "usuarioID", usuarioID ) );

        if( orientadores.isEmpty() )
            return null;

        return orientadores.get( 0 );
    }

    public boolean isLoginIMEExistente(
        String loginIME )
    {
        List<Orientador> orientadores = orientadorDAO.findByCriteria( 
        		Restrictions.eq( "loginIME", loginIME ) );

        if( orientadores.isEmpty() )
            return false;

        return true;
    }
    
    public void salvarAreasDePesquisa(
        Long professorID,
        List<Long> areasIncluidas)
    {
        if( areasIncluidas == null )
            areasIncluidas = new ArrayList<Long>();
		
        Orientador orientador = orientadorDAO.findById(professorID);

    	Set<AreaDePesquisa> areasDePesquisa = new HashSet<AreaDePesquisa>(orientador.getAreasDePesquisa());
    	
    	for( AreaDePesquisa areaDePesquisa : areasDePesquisa )
    	{
    		if(!areasIncluidas.contains(areaDePesquisa.getAreaDePesquisaID()))
    			orientador.removerAreaDePesquisa(areaDePesquisa);
    	}
    	
    	for( Long areaDePesquisaID : areasIncluidas )
    	{
    		if(!orientador.getAreasDePesquisa().contains(areaDePesquisaID))
    		{
    			AreaDePesquisa areaDePesquisa = areaDePesquisaDAO.findById(areaDePesquisaID);
    			orientador.inserirAreaDePesquisa(areaDePesquisa);
    		}
    	}
    	
    	orientadorDAO.saveOrUpdate(orientador);
    }

    public void salvarQuantidadeDeOrientandosDesejados(
        Long usuarioId,
        int quantidadeOrientandos )
    {
        
        Orientador orientador =  new Orientador();
            
        orientador = orientadorDAO.findById(usuarioId);

        if (orientador == null)
            return;
        
        orientador.setQuantidadeOrientandosDesejados( quantidadeOrientandos );
        
        orientadorDAO.saveOrUpdate( orientador );
        
    }
    
}